#pragma once

#include <opencv2/opencv.hpp> 
using namespace cv;


/// <summary>
/// 自带色系滤镜
/// </summary>
/// <param name="image"></param>
void color_style_demo(Mat& image)
{
	Mat dst;

	int colormap[] =
	{
		COLORMAP_AUTUMN  ,
		COLORMAP_BONE  ,
		COLORMAP_JET  ,
		COLORMAP_WINTER  ,
		COLORMAP_RAINBOW ,
		COLORMAP_OCEAN ,
		COLORMAP_SUMMER  ,
		COLORMAP_SPRING  ,
		COLORMAP_COOL ,
		COLORMAP_HSV  ,
		COLORMAP_PINK ,
		COLORMAP_HOT
	};

	int index = 0;
	while (true)
	{
		int c = waitKey(70);
		if (c == 27)
		{
			break;
		}

		applyColorMap(image, dst, colormap[index % 12]);
		index++;
		imshow("color", dst);
	}
}

/// <summary>
/// 图像像素的逻辑操作，位操作
/// </summary>
/// <param name="image"></param>
void bitwise_demo(Mat& image)
{
	Mat m1 = Mat::zeros(Size(256, 256), CV_8UC3);
	Mat m2 = Mat::zeros(Size(256, 256), CV_8UC3);

	//建立矩形  
	//rect方法前两个参数指定左上角起点 后两个指定举行宽高
	//thickness 厚度  负数为填充  正数为边缘线宽度
	// linetype参数   LINE_8默认抗锯齿   LINE_AA图形学抗锯齿   
	rectangle(m1, Rect(100, 100, 80, 80), Scalar(255, 255, 0), -1, LINE_8, 0);
	rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0);

	imshow("m1", m1);
	imshow("m2", m2);

	//位操作
	Mat dst;
	// 且操作
	//bitwise_and(m1, m2, dst);
	// 或操作
	//bitwise_or(m1, m2, dst);
	//位操作 图像色取反操作  两种 
	//dst= ~image;
	//bitwise_not(m1, m2, dst);
	//图像像素异或操作
	bitwise_xor(m1, m2, dst);

	imshow("addbit", dst);

}

/// <summary>
///  图像通道分离混合
/// </summary>
/// <param name="image"></param>
void channels_demo(Mat& image)
{
	imshow("source image", image);
	//通道分离
	std::vector<Mat> mv;
	split(image, mv);
	//此处显示只有灰色
	imshow("B", mv[0]);
	imshow("G", mv[1]);
	imshow("R", mv[2]);

	//通道显示  将其他两个通道关闭为0  merge混合后 只显示2号通道的颜色
	Mat dst;
	mv[0] = 0;
	mv[1] = 0;
	merge(mv, dst);
	imshow("MR", dst);


	//通道混合 给出通道对换规则 0->2 1->1 2->0   
	int from_to[] = { 0,2,1,1,2,0 };
	//可用于多图像
	mixChannels(&image, 1, &dst, 1, from_to, 3);
	imshow("MIX", dst);
}

/// <summary>
/// 图像色彩空间转换2 绿幕效果
/// </summary>
/// <param name="image"></param>
void inrange_demo(Mat& image)
{
	Mat hsv;
	cvtColor(image, hsv, COLOR_BGR2HSV);

	Mat mask;
	//HSV 色彩空间提取   scalar内为HSV的通道取值提取范围  需查看HSV表 
	//此处提取绿色部分为分离为新图内的像素1   其余颜色在新图内为像素0  相当于对颜色做了范围遮罩
	inRange(hsv, Scalar(35, 43, 46), Scalar(77, 255, 255), mask);

	//创建纯红色图
	Mat redBack = Mat::zeros(image.size(), image.type());
	redBack = Scalar(40, 40, 200);

	//取反 将遮罩中需要保留的部分分离为白色 即像素不为0
	//由于之前遮罩像素为1的地方是背景，则取反 将背景像素转化为 0  非背景转为1
	bitwise_not(mask, mask);
	//此处将原图拷贝到纯红图上 并添加遮罩影响， 遮罩上背景范围像素为0  则拷贝时不进行原图的背景拷贝  做到主体和背景分离效果
	image.copyTo(redBack, mask);
	//故做到了绿幕效果
	imshow("mask", redBack);
}

/// <summary>
///  图像像素统计
/// </summary>
/// <param name="image"></param>
void pixel_statistic_demo(Mat& image)
{
	double maxv, minv;
	Point minLoc, maxLoc;

	std::vector<Mat> mv;
	split(image, mv);
	for (int i = 0; i < mv.size(); i++)
	{
		minMaxLoc(mv[i], &minv, &maxv, &minLoc, &maxLoc, Mat());
		std::cout << "chanNo:" << i << "min value" << minv << "max value" << maxv << std::endl;
	}
	Mat mean, stddev;
	meanStdDev(image, mean, stddev);
	std::cout << "means1:" << mean.at<double>(0, 0) << std::endl;
	std::cout << "means2:" << mean.at<double>(1, 0) << std::endl;
	std::cout << "means3:" << mean.at<double>(2, 0) << std::endl;

	std::cout << "stddev1:" << stddev.at<double>(0, 0) <<std::endl;
	std::cout << "stddev2:" << stddev.at<double>(1, 0) <<std::endl;
	std::cout << "stddev3:" << stddev.at<double>(2, 0) <<std::endl;

	std::cout << "means:" << mean << "\nstddev" << stddev << std::endl;

}
